package com.jian.service.impl;


import com.alibaba.nacos.api.config.filter.IFilterConfig;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jian.common.ErrorCode;
import com.jian.constant.UserContent;
import com.jian.domain.User;
import com.jian.exception.BusinessException;
import com.jian.mapper.UserMapper;
import com.jian.requstBody.UserUpdateRequest;
import com.jian.service.UserService;
import com.jian.utils.RedisToken;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;


/**
 * 用户服务实现类
 *
 * @author 18214
 */

@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
        implements UserService {

    private static final String SALT = "jian";

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public long userRegister(String account, String password, String checkPassword) {
        //账号不小于4位 密码不小于6位 校验密码 导入一个实用的包commons-lang3 apache的包
        if (StringUtils.isAnyBlank(account, password, checkPassword))
            throw new BusinessException(ErrorCode.PARAM_ERROR, "账号或密码为空");
        if (account.length() < 4 || password.length() < 6 || !password.equals(checkPassword))
            throw new BusinessException(ErrorCode.PARAM_ERROR, "账号或密码要求不符合");

        // 校验账号不能包含字符
        String regEx = "[`~!@#$%^&*() +=|{}':;',//[//].<>/?~！@#￥%……&*（）——+|{}【】‘；：”“’。，、？]";
        Matcher matcher = Pattern.compile(regEx).matcher(account);
        if (matcher.find())
            throw new BusinessException(ErrorCode.PARAM_ERROR, "账号或密码要求不符合");

        //账号不能重复
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_account", account); // 查询条件
        long count = count(queryWrapper);
        if (count > 0)
            throw new BusinessException(ErrorCode.PARAM_ERROR, "账号不能重复");

        // 给密码加密 MD5单向加密
        String encryptPasswd = DigestUtils.md5DigestAsHex((SALT + password).getBytes());

        // 保存账号
        User user = new User();
        user.setUserAccount(account);
        user.setUserPassword(encryptPasswd);
        boolean result = save(user);

        if (!result)
            throw new BusinessException(ErrorCode.SAVE_ERROR, "账号存储失败");

        return user.getId();
    }

    @Override
    public User userLogin(String account, String password, HttpServletRequest request) {
        //账号不小于4位 密码不小于6位
        if (StringUtils.isAnyBlank(account, password))
            throw new BusinessException(ErrorCode.PARAM_ERROR, "账号或密码为空");
        if (account.length() < 4 || password.length() < 6)
            throw new BusinessException(ErrorCode.PARAM_ERROR, "账号或密码要求不符合");

        // 校验账号不能包含字符
        String regEx = "[`~!@#$%^&*() +=|{}':;',//[//].<>/?~！@#￥%……&*（）——+|{}【】‘；：”“’。，、？]";
        Matcher matcher = Pattern.compile(regEx).matcher(account);
        if (matcher.find())
            throw new BusinessException(ErrorCode.PARAM_ERROR, "账号或密码要求不符合");

        // 查看数据库中是否存在账号
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_account", account); // 查询条件
        User result = getOne(queryWrapper);
        if (result == null) {
            throw new BusinessException(ErrorCode.PARAM_ERROR, "账号或密码错误");
        }

        // 查看密码是否匹配 md5加密之后的代码
        String encryptPasswd = DigestUtils.md5DigestAsHex((SALT + password).getBytes());
        if (!result.getUserPassword().equals(encryptPasswd)) {
            throw new BusinessException(ErrorCode.PARAM_ERROR, "账号或密码错误");
        }

        // 脱敏
        User safetyResult = safetyUser(result);

        // 记录用户的登录态
//        request.getSession().setAttribute(USER_LOGIN_STATUS, safetyResult);
        // 使用redis记录用户登录信息 根据token为键
        String token = UUID.randomUUID().toString();
        RedisToken.saveToRedis(redisTemplate, token, safetyResult);
        // 设置返回的token
        result.setToken(token);
        return result;
    }

    public User safetyUser(User originUser) {
        if (originUser == null) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "参数为空");
        }
        User user = new User();
        user.setId(originUser.getId());
        user.setUserName(originUser.getUserName());
        user.setUserAccount(originUser.getUserAccount());
        user.setUserPassword(null);
        user.setAvatarUrl(originUser.getAvatarUrl());
        user.setGender(originUser.getGender());
        user.setPhone(originUser.getPhone());
        user.setEmail(originUser.getEmail());
        user.setUserStatus(originUser.getUserStatus());
        user.setCreateTime(originUser.getCreateTime());
        user.setUpdateTime(originUser.getUpdateTime());
        user.setIsDelete(null);
        user.setUserRole(originUser.getUserRole());
        return user;
    }

    @Override
    public List<User> searchUsers() {
//        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
//        if (StringUtils.isNotBlank(userAccount))
//            queryWrapper.like("userAccount", userAccount);

        List<User> list = list();

        return list.stream().map(this::safetyUser).collect(Collectors.toList());
    }

    @Override
    public void userLogout(HttpServletRequest request, String token) {
//        request.getSession().removeAttribute(USER_LOGIN_STATUS);
        RedisToken.delFromToken(redisTemplate, token);
    }

    @Override
    public Boolean userUpdateInfo(UserUpdateRequest newUser) {
        if (newUser == null)
            throw new BusinessException(ErrorCode.PARAM_ERROR, "需要修改的用户信息为空");
        if (newUser.getId() <= 0)
            throw new BusinessException(ErrorCode.PARAM_ERROR, "需要修改的用户id错误");
        User user = new User();
        user.setId(newUser.getId());
        user.setUserName(newUser.getUserName());
        user.setGender(newUser.getGender());
        user.setEmail(newUser.getEmail());
        user.setAvatarUrl(newUser.getAvatarUrl());
        user.setPhone(newUser.getPhone());
        return updateById(user);
    }

    @Override
    public int currentUserRole(String token) {
        User user = RedisToken.readFromRedis(redisTemplate, token, User.class);
        if (user == null || user.getId() == null)
            return UserContent.NOT_LOGIN;
        if (user.getUserRole() == UserContent.USER)
            return UserContent.USER;
        if (user.getUserRole() == UserContent.ADMINISTRATOR)
            return UserContent.ADMINISTRATOR;
        if (user.getUserRole() == UserContent.COURIER)
            return UserContent.COURIER;
        throw new BusinessException(ErrorCode.PARAM_ERROR, "身份不明确");
    }
}
